import { Controller, Post, Body, Get, Delete, Param, Put, UseGuards, Query } from '@nestjs/common';
import { ApiOperation, ApiUseTags, ApiModelProperty, ApiBearerAuth, ApiImplicitQuery } from '@nestjs/swagger';
import { IsNotEmpty } from 'class-validator';
import { ReturnModelType, DocumentType } from '@typegoose/typegoose';
import { InjectModel } from 'nestjs-typegoose';
import { User } from '@lib/db/models/user.model';
import updataUserDto from './dto/updataUser';
import { AuthGuard } from '@nestjs/passport';
import { JwtService } from '@nestjs/jwt';
import { CurrentUser } from './current-user.decorator';
import { tryParseIntPipe } from './pipe/parseInt.pipe';
import { queryOptionDto } from './dto/queryOption';
import getQueryOption from './dto/getQueryOption';

class RegisterDto extends User {
  @ApiModelProperty({ description: '用户名', example: 'admin' })
  @IsNotEmpty({ message: '请填写用户名' })
  username: string

  @ApiModelProperty({ description: '密码', example: '123456aa' })
  @IsNotEmpty({ message: '请输入密码' })
  password: string
}
class LoginDto {
  @ApiModelProperty({ description: '用户名', example: 'hahaha' })
  @IsNotEmpty({ message: '请填写用户名' })
  username: string

  @ApiModelProperty({ description: '密码', example: '123456' })
  @IsNotEmpty({ message: '请输入密码' })
  password: string
}

@Controller('auth')
@ApiUseTags('用户')
export class AutoController {
  constructor(
    private readonly jwtService: JwtService,
    @InjectModel(User) private userModel: ReturnModelType<typeof User>,
  ) { }

  @ApiOperation({ title: '注册' })
  @Post('register')
  async register(@Body() dto: RegisterDto) {
    const obj = await this.userModel.create(dto)
    return obj
  }

  @ApiOperation({ title: '登录-用户校验  获取token' })
  @UseGuards(AuthGuard('local'))
  @Post('login')
  async login(@Body() login: LoginDto, @CurrentUser() user: DocumentType<User>) {
    return {
      token: await this.jwtService.signAsync(String(user._id))
    }
  }

  @Get('user')
  @ApiOperation({ title: '获取个人信息' })
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  async user(@CurrentUser() user: DocumentType<User>) {
    return user
  }

  @ApiOperation({ title: '获取单个用户信息' })
  @Get('users/:id')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  async getUser(@Param('id') id: string) {
    const user = await this.userModel.findById(id)
    return user
  }

  @ApiOperation({ title: '获取所有用户信息' })
  @Get('users')
  // @UseGuards(AuthGuard('jwt')) 
  // @ApiBearerAuth()
  @ApiImplicitQuery({
    description: `这里写 = 后面的那个
    /users?query={"where":{"username":"user1","age":{"$gt":18}},"sort":"-_id","limit":10,"skip":1}
    可参考 getQueryOption`,
    required: false,
    type: queryOptionDto,
    name: 'query',
  })
  async getUsers(@Query('query', new tryParseIntPipe()) query?: queryOptionDto): Promise<object> {
    const { where = {}, skip = 0, limit = 10, sort = 'acs' } = query as getQueryOption
    const users = await this.userModel.find().where(where).skip(skip).limit(limit).sort(sort).populate('roles').populate('permission').populate({
      path: 'roles',
      populate: {
        path: 'permission'
      }
    }).exec()
    const total = await this.userModel.countDocuments(where)
    return {
      data: users,
      total,
      lastPage: Math.ceil(total / limit),
      currentPage: (skip && limit) ? Math.ceil(skip / limit) : 1,
    }
  }

  @ApiOperation({ title: '删除单个用户' })
  @Delete('users/:id')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  async deleteUser(@Param('id') id: string) {
    const flag = await this.userModel.findByIdAndDelete(id)
    return flag
  }

  @ApiOperation({ title: '修改用户信息' })
  @Put('users/:id')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  async updataUser(@Param('id') id: string, @Body() user: updataUserDto) {
    const newUser = await this.userModel.findByIdAndUpdate(id, user)
    return newUser
  }

}
